﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Framework.FSM;
using BridgeShips.AI;
using Framework.Entity;

namespace BridgeShips.FSM {

    /*
     *  辅助并线 探测 虚拟席位
     */
    public class VHalfWayProbeState : IFsmState {


        private float m_KeepTime = 0.0f;
        private uint m_VirtrualID = 0; //ship id
        private int m_needChangeRotation = -1;
        // Use this for initialization
        /// <summary>
        /// 状态初始化接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Init( IFSM fsm ) {

    }
        /// <summary>
        /// 状态开始接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        /// <param name="data">状态数据</param>
        public void Enter( IFSM fsm, FsmStateDataBase data ) {
            m_VirtrualID = data.index;
            m_KeepTime = Time.time; 
            Debug.LogError("VHalfWayProbeState" );
        }
        /// 状态暂停接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Pause( IFSM fsm ) {
        }
        /// <summary>
        /// 状态恢复接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Resume( IFSM fsm ) {
        }
        /// <summary>
        /// 状态重置接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Reset( IFSM fsm ) {
        }
        /// <summary>
        /// 状态离开接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Exit( IFSM fsm ) {
        }
        /// <summary>
        /// 状态销毁接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Destroy( IFSM fsm ) {
        }
        /// <summary>
        /// VHalfWayProbeState 状态更新函数
        /// </summary>
        /// <param name="frameTime">逻辑一帧时间</param>
        /// <param name="realTime">实际一帧时间</param>
        public void Update( float frameTime, float realTime ) {

            if (m_VirtrualID <= 0)
                return;
            FsmStateDataBase fsdb = GameEntry.Instance.VirtualRManager.GetDataBaseByIndex( m_VirtrualID );
            if (fsdb == null)
                return;

            Transform trans = GameEntry.Instance.EntityManager.ObjTransform( fsdb.vShipID );
            if (trans == null)
                return;

            int needVShipRoation = CaculateLeftOrRight( trans.position );
            if (m_needChangeRotation != needVShipRoation) {
                float needDeg = (needVShipRoation * 0.5f + 0.5f) * 180.0f;
                fsdb.virtualObj.transform.localRotation = Quaternion.Euler( Vector3.up * needDeg );
                m_needChangeRotation = needVShipRoation;
            }
          //  float distance = Vector3.Distance( fsdb.virtualObj.transform.position, trans.position );
            IEntity entity = GameEntry.Instance.EntityManager.Get(fsdb.vShipID);
            if ( entity.GetAI().Settings.Detection.HasTarget() ) {

                IEntity eTarget = GameEntry.Instance.EntityManager.Get(fsdb.vlinkingTargetID);
                if (eTarget == null)
                    return;
                float distance = Vector3.Distance(eTarget.Get().transform.position, entity.Get().transform.position);
                ET.AIMovementState eAIState = entity.GetAI().Settings.Movement.MovementState;
                if (Time.time - m_KeepTime > 15.0f  && (distance > fsdb.length - 1.0f  && distance < fsdb.length + 1.0f) && eAIState <= ET.AIMovementState.WaitingIdle)
                {
                    GameEntry.Instance.FsmManager.GetFsm(entity.Get().name).ChangeState<VHalfWayPosCorrectState>(fsdb);
                    m_KeepTime = Time.time;
                }
            }
            else
            {
                m_KeepTime = Time.time;
            }
        }

        public int CaculateLeftOrRight( Vector3 shipPosition ) {
            Vector3 verticalDir = TerrainsMove.Instance.GetBridgePoint2().position - TerrainsMove.Instance.GetBridgePoint1().position;
            verticalDir.Normalize();
            Vector3 direction = (shipPosition - TerrainsMove.Instance.GetBridgePoint1().position).normalized;
            int flag = 1;  //左0 右1
            if (Vector3.Cross( direction, verticalDir ).y > 0) {
                flag = -1;
            }
            else {
                flag = 1;
            }
            return flag;
        }
    }


    /*
     *  辅助并线 席位矫正
     */
    public class VHalfWayPosCorrectState : IFsmState {


        private uint m_VirtrualID = 0; //ship id
        // Use this for initialization
        /// <summary>
        /// 状态初始化接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Init( IFSM fsm ) {
        }
        /// <summary>
        /// 状态开始接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        /// <param name="data">状态数据</param>
        public void Enter( IFSM fsm, FsmStateDataBase data ) {
            m_VirtrualID = data.index;
            Debug.LogError("VHalfWayProbeState");
        }
        /// 状态暂停接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Pause( IFSM fsm ) {
        }
        /// <summary>
        /// 状态恢复接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Resume( IFSM fsm ) {
        }
        /// <summary>
        /// 状态重置接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Reset( IFSM fsm ) {
        }
        /// <summary>
        /// 状态离开接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Exit( IFSM fsm ) {
        }
        /// <summary>
        /// 状态销毁接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Destroy( IFSM fsm ) {
        }
        /// <summary>
        /// 状态更新函数
        /// </summary>
        /// <param name="frameTime">逻辑一帧时间</param>
        /// <param name="realTime">实际一帧时间</param>
        /// 

        private int LeftOrRightLocation(IEntity ship, IEntity target, ShipTypes sType)
        {
            Vector3 direction = (target.Position() - ship.Position()).normalized;
            int flag = 1;  //左0 右1
            float locate = 0.0f;
            if (sType == ShipTypes.StraddleType)
            {
                locate = Vector3.Cross(ship.Get().transform.forward, direction).y;
            }
            else if (sType == ShipTypes.LineType)
            {
                locate = Vector3.Cross(ship.Get().transform.right, direction).y;
            }
            if (locate > 0)
            {
                flag = -1;
            }
            else
            {
                flag = 1;
            }
            return flag;
        }

        private void MovementForLinking( AIShip ship, IEntity eTarget ) {
            IEntity shipEntity = ship.Settings.Detection.GetEnity();
            if (shipEntity != null) {
                // shipEntity.GetID
                ShipTypes sType = ship.Settings.GetShipPattern();
                int locaIndex = LeftOrRightLocation(shipEntity, eTarget, sType) * -1;
                float targetLenght = (ship.Settings.BridgeShipLenght + eTarget.GetAI().Settings.BridgeShipLenght) * 0.5f;
                Vector3 vecDestination = Vector3.zero;
                if (sType == ShipTypes.StraddleType)
                {
                    vecDestination = eTarget.Get().transform.TransformPoint(new Vector3(targetLenght * locaIndex, 0.0f, 0.0f));
                }
                else if (sType == ShipTypes.LineType)
                {
                    vecDestination  = eTarget.Get().transform.TransformPoint(new Vector3(0.0f, 0.0f, targetLenght * locaIndex));
                }
               
                vecDestination.y = 7.0f;
                Debug.DrawLine(shipEntity.Get().transform.position, vecDestination, Color.cyan, 15.0f);
                if (Vector3.Distance(shipEntity.Get().transform.position, vecDestination) > ship.Settings.BridgeShipLenght * 0.5f)
                    return;
                ship.Settings.Movement.MoveTo( vecDestination, eTarget.Get().transform.forward );
            }
        }
        //VHalfWayPosCorrectState  智能并线
        public void Update( float frameTime, float realTime ) {
            if (m_VirtrualID <= 0)
                return;

            FsmStateDataBase fsdb = GameEntry.Instance.VirtualRManager.GetDataBaseByIndex( m_VirtrualID );
            if (fsdb == null)
                return;


            IEntity entity = GameEntry.Instance.EntityManager.Get(fsdb.vShipID);
            if (entity == null)
                return;
            if (!entity.GetAI().Settings.Detection.HasTarget())
            {
                GameEntry.Instance.FsmManager.GetFsm(entity.Get().name).ChangeState<VHalfWayProbeState>(fsdb);
            }
               

            IEntity eTarget = GameEntry.Instance.EntityManager.Get(fsdb.vlinkingTargetID);
            if (eTarget == null)
                return;

            ET.AIMovementState mstate = entity.GetAI().ShipMoveState();

            float distance = Vector3.Distance(eTarget.Get().transform.position, entity.Get().transform.position );
            if (entity.GetAI().Settings.Detection.HasTarget())
            {
                if (entity.GetAI().Settings.IsDone())
                {
                    GameEntry.Instance.FsmManager.GetFsm(entity.Get().name).ChangeState<VHalfWayLinkingState>(fsdb);
                    return;
                }

                if (distance > fsdb.length - 1.0f && distance < fsdb.length + 2.0f  + GameEntry.Instance.VirtualRManager.faultTolerant)
                {
                    MovementForLinking(entity.GetAI(), eTarget);
                }
                else if (distance < fsdb.length)
                {
                    // GameEntry.Instance.FsmManager.GetFsm(entity.Get().name).ChangeState<VHalfWayIdleState>(fsdb);

                    var meshRender = fsdb.virtualObj.GetComponentInChildren<MeshRenderer>();
                    if (meshRender != null)
                    {
                        meshRender.material.SetFloat("_WireThickness", Mathf.Clamp(150.0f * distance + 580.0f, 500.0f, 760.0f));

                    }

                }
            }
            else
            {
                GameEntry.Instance.FsmManager.GetFsm(entity.Get().name).ChangeState<VHalfWayProbeState>(fsdb);
            }
        }
    }


    /*
     *  辅助并线 等待状态
     */
    public class VHalfWayLinkingState : IFsmState {

        private uint m_VirtrualID = 0; //ship id
        private float m_realKeepTime = 0.0f;//链接保持时间
        private float m_MaxKeepTime = 10.0f;//最大准备链接保持时间
        // Use this for initialization
        /// <summary>
        /// 状态初始化接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Init( IFSM fsm ) {
        }
        /// <summary>
        /// 状态开始接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        /// <param name="data">状态数据</param>
        public void Enter( IFSM fsm, FsmStateDataBase data ) {
            m_VirtrualID = data.index;
            Debug.LogError("VHalfWayLinkingState");
        }
        /// 状态暂停接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Pause( IFSM fsm ) {
        }
        /// <summary>
        /// 状态恢复接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Resume( IFSM fsm ) {
        }
        /// <summary>
        /// 状态重置接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Reset( IFSM fsm ) {
        }
        /// <summary>
        /// 状态离开接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Exit( IFSM fsm ) {
            m_realKeepTime = 0.0f;
        }
        /// <summary>
        /// 状态销毁接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Destroy( IFSM fsm ) {
        }
        /// <summary>
        /// 状态更新函数
        /// </summary>
        /// <param name="frameTime">逻辑一帧时间</param>
        /// <param name="realTime">实际一帧时间</param>
        /// 
        //VHalfWayLinkingState
        public void Update( float frameTime, float realTime ) {

            if (m_VirtrualID <= 0)
                return;

            FsmStateDataBase fsdb = GameEntry.Instance.VirtualRManager.GetDataBaseByIndex( m_VirtrualID );
            if (fsdb == null)
                return;

            m_realKeepTime += frameTime;

            Transform trans = GameEntry.Instance.EntityManager.ObjTransform( fsdb.vShipID );
            if (trans == null)
                return;

            bool beFar = TransferOfAxes.Instance.linkedEachOtherFarfromSetPoint( trans.position );
            if (!beFar && GameEntry.Instance.FsmManager.GetOpenAuxillaryConnection()) {
                GameEntry.Instance.FsmManager.GetFsm( trans.name ).ChangeState<VHalfWayIdleState>( fsdb );
                return;
            }
            IEntity entity = GameEntry.Instance.EntityManager.Get(fsdb.vShipID);
            if (entity.GetAI().Settings.Detection.HasTarget())
            {
                if (m_realKeepTime >= m_MaxKeepTime)
                {
                    if (entity != null)
                    {
                        entity.GetAI().Settings.Movement.MakeLinked(true);

                        //StateData.OverrideValue(HelpStrings.AI.IS_SHIP_LINKED, entity.GetAI().Settings.Detection.HasTarget(), entity.GetAI().WorldState);
                        if (beFar)
                        {
                           // GameEntry.Instance.CombinedDeformationManager.GenCompineDeformation(fsdb.vShipID, fsdb.vlinkingTargetID);
                        }
                        GameEntry.Instance.FsmManager.GetFsm(entity.Get().name).ChangeState<VHalfWayIdleState>(fsdb);
                    }
                }
                else
                {
                    IEntity eTarget = GameEntry.Instance.EntityManager.Get(fsdb.vlinkingTargetID);

                    var shipPro = ShipsDictionary.Instance.shipDic[fsdb.vlinkingTargetID];
                    float distance = Vector3.Distance(shipPro.CenterPosition, entity.Get().transform.position);
                    if (entity.GetAI().Settings.Detection.HasTarget() == false || eTarget == null || (distance > fsdb.length + 3.0f + GameEntry.Instance.VirtualRManager.faultTolerant))
                    {
                        Debug.LogError("m_realKeepTime" + m_realKeepTime); 
                        m_realKeepTime = 0.0f;
                        GameEntry.Instance.FsmManager.GetFsm(entity.Get().name).ChangeState<VHalfWayProbeState>(fsdb);
                    }
                }
            }
          
        }
    }


    /*
     *  辅助并线 等待状态
     */
    public class VHalfWayIdleState : IFsmState {

        private float m_KeepTime = 0.0f;
        private uint m_VirtrualID = 0; //ship id
        // Use this for initialization
        /// <summary>
        /// 状态初始化接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Init( IFSM fsm ) {
        }
        /// <summary>
        /// 状态开始接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        /// <param name="data">状态数据</param>
        public void Enter( IFSM fsm, FsmStateDataBase data ) {
            m_VirtrualID = data.index;
            m_KeepTime = Time.time;
            Debug.LogError("VHalfWayIdleState");
        }
        /// 状态暂停接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Pause( IFSM fsm ) {
        }
        /// <summary>
        /// 状态恢复接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Resume( IFSM fsm ) {
        }
        /// <summary>
        /// 状态重置接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Reset( IFSM fsm ) {
        }
        /// <summary>
        /// 状态离开接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Exit( IFSM fsm ) {
        }
        /// <summary>
        /// 状态销毁接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Destroy( IFSM fsm ) {
        }
        /// <summary>
        /// 状态更新函数
        /// </summary>
        /// <param name="frameTime">逻辑一帧时间</param>
        /// <param name="realTime">实际一帧时间</param>
        public void Update( float frameTime, float realTime ) {

            if (m_VirtrualID <= 0)
                return;

            FsmStateDataBase fsdb = GameEntry.Instance.VirtualRManager.GetDataBaseByIndex( m_VirtrualID );
            if (fsdb == null)
                return;

            //Transform trans = GameEntry.Instance.EntityManager.ObjTransform( fsdb.vShipID );
            //if (trans == null)
            //    return;

            IEntity entity = GameEntry.Instance.EntityManager.Get( fsdb.vShipID );
            if (entity != null) {
                //if ((Time.time - m_KeepTime > 10.0f) && (entity.GetAI().ShipMoveState() != ET.AIMovementState.WaitingIdle )) {
                //    m_KeepTime = Time.time;
                //    GameEntry.Instance.FsmManager.GetFsm(entity.Get().name).ChangeState<VHalfWayProbeState>(fsdb);
                //}
               var shipProperty =  ShipsDictionary.Instance.shipDic[fsdb.vShipID];
                if (shipProperty == null) return;
                float distance = Vector3.Distance(shipProperty.CenterPosition, entity.Get().transform.position);
                if (distance > fsdb.length * 0.5f)
                {
                    GameEntry.Instance.FsmManager.GetFsm(entity.Get().name).ChangeState<VHalfWayProbeState>(fsdb);
                }
            }
        }
    }


    /*
     *  辅助并线 等待状态
     */
    public class VHalfWayLeaveState : IFsmState {


        private uint m_VirtrualID = 0; //ship id
                                       // Use this for initialization
                                       /// <summary>
                                       /// 状态初始化接口
                                       /// </summary>
                                       /// <param name="fsm">状态属于的状态机</param>
        public void Init( IFSM fsm ) {
        }
        /// <summary>
        /// 状态开始接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        /// <param name="data">状态数据</param>
        public void Enter( IFSM fsm, FsmStateDataBase data ) {
            m_VirtrualID = data.index;

            Debug.LogError("VHalfWaVHalfWayLeaveStateyProbeState");
        }
        /// 状态暂停接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Pause( IFSM fsm ) {
        }
        /// <summary>
        /// 状态恢复接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Resume( IFSM fsm ) {
        }
        /// <summary>
        /// 状态重置接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Reset( IFSM fsm ) {
        }
        /// <summary>
        /// 状态离开接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Exit( IFSM fsm ) {

        }
        /// <summary>
        /// 状态销毁接口
        /// </summary>
        /// <param name="fsm">状态属于的状态机</param>
        public void Destroy( IFSM fsm ) {
        }
        /// <summary>
        /// VHalfWayLeaveState状态更新函数
        /// </summary>
        /// <param name="frameTime">逻辑一帧时间</param>
        /// <param name="realTime">实际一帧时间</param>
        public void Update( float frameTime, float realTime ) {

            if (m_VirtrualID <= 0)
                return;
            FsmStateDataBase fsdb = GameEntry.Instance.VirtualRManager.GetDataBaseByIndex(m_VirtrualID);
            if (fsdb == null)
                return;

            Transform trans = GameEntry.Instance.EntityManager.ObjTransform( fsdb.vShipID );
            if (trans == null)
                return;

            IEntity entity = GameEntry.Instance.EntityManager.Get(fsdb.vShipID);
            if (entity != null)
            {
                float distance = Vector3.Distance(fsdb.virtualObj.transform.position, trans.position);
                if (distance > fsdb.length * 0.65f)
                {
                    GameEntry.Instance.FsmManager.GetFsm(entity.Get().name).ChangeState<VHalfWayProbeState>(fsdb);
                }
            }
        }
    }
}
